\chapter{Site Object API}
\label{chap:site}

Gantry.pm and its engines provide a rich API client apps can rely on.
This chapter provides highlights of the API.  Full details are left
to Gantry.pm and the engines themselves.
After the API section, is a short section explaining the basic
requirements for writing your own engine.  As bonus, there is also a
section on using and writing template engines (which are much simpler).

\section{The API\index{API, Gantry}\index{Gantry!API}}

Table \ref{tab:sitemethods} shows off many useful methods you can call on
your site object.
Keep in mind that these are only highlights of the most important methods.
Full details are reserved to the docs within Gantry.pm and each engine.
Look for the engines in the Gantry::Engine:: namespace.
Note that all methods are called through the current Gantry site object,
but most of them do not receive arguments beyond that invocant.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
General Methods    & Receives & Returns \\
\hline
\verb+get_param_hash+    & & hash of form params             \\
\verb+get_arg_hash+      & & hash of query string            \\
                         & & params                          \\
\verb+base_server+       & & host name of server             \\
\verb+current_url+       & & full url of current page        \\
                         & & including \verb+http:+          \\
\verb+dispatch_location+ & & concatenates current            \\
                         & & uri and location                \\
\verb+fish_config+       & param name & value of requested   \\
                         &            & config param         \\
\verb+get_cookies+       & optional name & get one or all    \\
                         &               & cookies (hashref) \\
\verb+r+                 & & Apache request object           \\
                         & & \verb+mod_perl+ only            \\
\verb+set_cookies+       & options & set one or more         \\
                         &         & cookies, see docs       \\
\hline
\multicolumn{2}{l}{Disk Path Methods}
& absolute disk path to.. \\
\hline
\verb+root+      & & templates \\
\verb+css_root+  & & css files \\
\verb+img_root+  & & images    \\
\hline
\multicolumn{2}{l}{URL Path Methods} & URL path from \\
\multicolumn{2}{l}{}                 & DocumentRoot to ...\\
\hline
\verb+app_rootp+ & & app's base location \\
\verb+css_rootp+ & & style sheets        \\
\verb+img_rootp+ & & images              \\
\verb+web_rootp+ & & app's web content   \\
\hline
\multicolumn{3}{l}{Template Control Methods (Accessors)} \\
\hline
\verb+template+          & & template file for this \\
                         & & page usually a setter     \\
\verb+template_default+  & & default if no template    \\
                         & & is defined                \\
\verb+template_wrapper+  & & TT wrapper                \\
\hline
\multicolumn{2}{l}{Request Methods(Getters)}
& like calling request \\
\multicolumn{2}{l}{ }
& object method... \\
\hline
\verb+uri+            & & \verb+uri+            \\
\verb+location+       & & \verb+location+       \\
\verb+path_info+      & & \verb+path_info+      \\
\verb+content_type+   & & \verb+content_type+   \\
\verb+content_length+ & & \verb+content_length+ \\
\end{tabular}
\end{center}
\caption{Highlighted methods from the Gantry site object API.}
\label{tab:sitemethods}
\end{table}

Engines could choose to export additional methods, but
callers using them would risk incompatability should they ever
switch engines.

Remember that all the engines provide all the methods in Table
\ref{tab:sitemethods}.  So, even
in CGI you can call all of them. The CGI engine spoofs the \verb+mod_perl+
behavior as necessary, but don't expect it to give you a useable
Apache request object.

\section{Implementing an Engine}

Gantry engines\index{engine!implementing}\index{Gantry!engine implementation}
are mixins which provide a bridge between the rather abstract
way Gantry handles requests and the particulars of your server.  Currently
Gantry ships with engines for \verb+mod_perl+ 1, \verb+mod_perl+ 2 and
CGI.  Though somewhat
tedious, it is not particularly difficult to implement your own engine.
This section explains how.

The namespace\index{namespace!for Gantry egines}
for engines is prescribed as Gantry::Engine::.
All engines are loaded from it by Gantry.pm's import method.  It
looks for them in only one namespace.

Fundamentally, engines are mixins.  This means they must export methods into
the user's namespace.  Since Gantry.pm is the user of the modules, their
methods are available through the site object.  This allows everyone
to use them: Gantry.pm itself, its helpers, and app specific modules.

Thus, the basic form of an engine is like this:

{\footnotesize
\begin{verbatim}
package Gantry::Engine::YourEngine;
use strict;

use base 'Exporter';

our @EXPORT = qw(
    # mixin methods here
);
\end{verbatim}
}

A partial list of the methods and what they must do is in the first section of
this chapter.  For a complete list, look in either of the \verb+mod_perl+ 
engines.  But, there are still a few other things that you will need
in your preamble.  Chief among these is:

{\footnotesize
\begin{verbatim}
use Gantry::Utils::DBConnHelper::YourEngine;
use Gantry::Conf;
\end{verbatim}
}

This implies that your have implemented
\verb+YourEngine.pm+, which must provide database
connection information by fishing it out of the configuration parameters.
There are six methods in any
connection helper.\index{database connection helpers}
Three are for auth
connections, three are for regular connections.  For example, this allows
apps to look up auth in a central database while having their own app
specific database for other tables.  Normally, helpers return the regular
information if no auth information is available.

As a courtesy, helpers should try to fish the connection information via
Gantry::Conf, before falling back on other approaches.  If you don't do
that, Gantry::Conf users will not be pleased.
The methods are shown in Table \ref{tab:connmethods}.
Some helpers choose to provide set accessors for their connection info.
This is particularly helpful for scripts which might want to just plug
in data from the command line.
You probably also need to include things morally equivalent to
Apache::Constants and Apache::Request.
Please also use Gantry::Conf.  Though not required, it is nice to be
able to seemlessly deploy apps with it, but this requires all
engines to use it as their first choice for obtaining conf info.

\begin{table}
\begin{center}
\begin{tabular}{l|l|l}
Method & Receives & Returns \\
\hline
\verb+get_dbh+            &       & the regular dbh                \\
\verb+set_dbh+            & a dbh &                                \\
\verb+get_conn_info+      &       & a hash ref with these keys:    \\
                          &       & \verb+dbconn+, \verb+dbuser+,
                                    \verb+dbpass+                  \\
\hline
\verb+get_auth_dbh+       &       & the auth dbh                   \\
\verb+set_auth_dbh+       & a dbh &                                \\
\verb+get_auth_conn_info+ &       & a hash ref with these keys:    \\
                          &       & \verb+auth_dbconn+             \\
                          &       & \verb+auth_dbuser+             \\
                          &       & \verb+auth_dbpass+             \\
\end{tabular}
\end{center}
\caption{API for DBI connections helpers for use with Class::DBI and
native models.}
\label{tab:connmethods}
\end{table}

\section{Template Engine API}
\label{sec:templateengineapi}

There are only four methods in the Gantry template
API\index{template!API}\index{Gantry!template API}
as you can see from
Table \ref{tab:templateapi}.
You need to implement \verb+do_error+,\index{do error@\verb+do_error+}
but you don't need to do anything in
it.  Gantry will log errors through the web server with whatever is the
normal plan.  You could implement your own template engine, based on an
existing one, just for the purpose of controlling logged information in
this method.

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Method & Purpose \\
\hline
\verb+do_action+       & called on to perform a \verb+do_+ method and \\
                       & store its returned output                    \\
\verb+do_error+        & often does nothing, but could log            \\
\verb+do_process+      & using only the Gantry site object, returns   \\
                       & formated output                              \\
\verb+template_engine+ & returns the name of the template package     \\
\end{tabular}
\end{center}
\caption{Complete template engine API.}
\label{tab:templateapi}
\end{table}

When Gantry's single handler figures out what \verb+do_*+ method to call, 
it actually calls \verb+do_action+,\index{do process@\verb+do_process+}
which is provided by the template
engine.  Normally, \verb+do_action+ calls the action method and stores
the result in the \verb+stash+.

After the \verb+do_*+ method returns, if there were no errors, Gantry's
handler calls \verb+do_process+ on the template engine.  It is responsible
for feeding the data, collected from the \verb+do_*+ method during
\verb+do_action+,\index{do action@\verb+do_action+}
to the template engine.  The returned result needs to
be presentable to the browser.

Implementing a template engine is as easy as implementing the methods just
described and exporting those methods by default from a module in the
Gantry::Template::* namespace.

\subsection{Unorthodox Template Processing}
\label{ssec:templateproc}

Most Gantry \verb+do_*+ methods set the \verb+template+ attribute
on the Gantry site object and return a data structure which that
template understands.  Sometimes that does not provide enough flexibility.
Suppose, for example, that you need to return a JSON response to an
AJAX\index{AJAX responses}
request.  You need to turn off templating temporarily.  Here's how.
In your controller, you may turn off your templating engine by setting
the \verb+template_disable+\index{template!disabling}
attribute to a true value:

{\footnotesize
\begin{verbatim}
    $self->template_disable( 1 );
\end{verbatim}
}
\noindent
Then whatever you return will be given directly to the browser.

But, what if you want to form part of the AJAX response with templates?
Or, perhaps you want to build template data with
templates.
At any point in a \verb+do_*+ method, you may
call \verb+do_process+,\index{do process@\verb+do_process+}
as in this example taken from
tentmaker\footnote{which is an AJAX intensive Gantry app}:

{\footnotesize
\begin{verbatim}
sub do_create_app_block {

    #... creation of new block not shown

    # now fill in the new app_body element
    my $new_divs     = '';

    $self->stash->view->template( 'new_app_body_div.tt' );
    $self->template_wrapper( 0 );  # turn off wrapping

    foreach my $new_block ( @new_blocks ) {
        my $block_hashes = $new_block->walk_postorder(
                'app_block_hashes'
        );

        $self->stash->view->data( 
            {
                block      => $block_hashes->[0],
                statements => $statements,
            }
        );

        eval {
            $new_divs .= $self->do_process( ) || '';
        };
        if ( $@ ) {
            warn "error: $@\n";
        }
    }

    $self->template_disable( 1 );

    return $self->stash->controller->data( $new_divs );
}
\end{verbatim}
}

This code is called when tentmaker makes a table for you\footnote{and at
other times}.  Recall that when tentmaker makes a table, it also makes
a corresponding controller.  The server needs to tell the browser about the
new HTML divs for the table and controller.

Code not shown above makes \verb+@new_blocks+.  Each block is happy
to provide the data the div template needs when I call
\verb+walk_postorder+ as shown.  That returns an array with one
element in it.\begin{footnote}
See the bigtop reference booklet to see why it's an array.
\end{footnote}  The call to \verb+$self->stash->view->data+
sets the Template Toolkit stash variables.  The \verb+eval+ protects
against errors of all kinds.

Calling \verb+do_process+ in a controller, when TT is your template
engine, does what you should expect.\footnote{If you expect it to feed
the data into the template by delegating to TT's own process method.}
The results are collected in \verb+$new_divs+.

Note that I can call process over and over again.  I could even
change templates on each request, by moving the call to
\verb+$self->stash->view->template+ inside the loop.

So, if you don't want your return value to be
sent through the template engine after you return it, set the
\verb+template_disable+ attribute as shown above.  But, don't set
it until after you use \verb+do_process+.  That method always bails out,
if the flag is set, and just returns the value of the
site's
\verb+stash->controller->data+ attribute.  In fact,
you are triggering that bail out whenever you set the
\verb+template_disable+ flag.

\section*{Summary}

In this chapter we have seen some highlights of the site object API
including the template API, which is mixed in to the site.  My emphasis
here is on common features rather than completeness.  Gantry.pm, the
engines, and the template engines have complete docs.  Refer to those
for more exotic methods.
